<template>
  <div
    class="notice-bar"
    :style="{ background, height: `${height}px` }"
    v-show="!state.isMode"
  >
    <div class="notice-bar-warp" :style="{ color, fontSize: `${size}px` }">
      <el-icon
        v-if="showLeftIcon"
        class="notice-bar-warp-left-icon"
        @click="onRightIconClick"
      >
        <slot name="leftIcon"></slot>
      </el-icon>
      <div class="notice-bar-warp-text-box" ref="noticeBarWarpRef">
        <div
          class="notice-bar-warp-text"
          ref="noticeBarTextRef"
          v-if="!scrollable"
        >
          {{ text }}
        </div>
        <div class="notice-bar-warp-slot" v-else><slot /></div>
      </div>
      <!--   <SvgIcon
        :name="rightIcon"
        v-if="rightIcon"
        class="notice-bar-warp-right-icon"
        @click="onRightIconClick"
      /> -->

      <el-icon
        v-if="showRightIcon"
        class="notice-bar-warp-right-icon"
        @click="onRightIconClick"
      >
        <slot name="rightIcon"></slot>
      </el-icon>
    </div>
  </div>
</template>

<script setup lang="ts" name="noticeBar">
import { reactive, ref, onMounted, computed, nextTick } from "vue";

// 定义父组件传过来的值
const props = defineProps({
  // 通知栏模式，可选值为 closeable link
  mode: {
    type: String,
    default: () => "",
  },
  // 通知文本内容
  text: {
    type: String,
    default: () => "",
  },
  // 通知文本颜色
  color: {
    type: String,
    default: () => "var(--el-color-warning)",
  },
  // 通知背景色
  background: {
    type: String,
    default: () => "var(--el-color-warning-light-9)",
  },
  // 字体大小，单位px
  size: {
    type: [Number, String],
    default: () => 14,
  },
  // 通知栏高度，单位px
  height: {
    type: Number,
    default: () => 40,
  },
  // 动画延迟时间 (s)
  delay: {
    type: Number,
    default: () => 1,
  },
  // 滚动速率 (px/s)
  speed: {
    type: Number,
    default: () => 100,
  },
  // 是否开启垂直滚动
  scrollable: {
    type: Boolean,
    default: () => false,
  },
  // 自定义左侧图标
  leftIcon: {
    type: Boolean,
    default: () => false,
  },
  // 自定义右侧图标
  rightIcon: {
    type: Boolean,
    default: () => false,
  },
});
// 计算有无传图标
const showLeftIcon = computed(() => {
  return props.leftIcon;
});
const showRightIcon = computed(() => {
  return props.rightIcon;
});
// 定义子组件向父组件传值/事件
const emit = defineEmits(["close", "link"]);

// 定义变量内容
const noticeBarWarpRef = ref();
const noticeBarTextRef = ref();
const state = reactive({
  order: 1,
  oneTime: 0,
  twoTime: 0,
  warpOWidth: 0,
  textOWidth: 0,
  isMode: false,
});

// 初始化 animation 各项参数
const initAnimation = () => {
  nextTick(() => {
    state.warpOWidth = noticeBarWarpRef.value.offsetWidth;
    state.textOWidth = noticeBarTextRef.value.offsetWidth;
    document.styleSheets[0].insertRule(
      `@keyframes oneAnimation {0% {left: 0px;} 100% {left: -${state.textOWidth}px;}}`
    );
    document.styleSheets[0].insertRule(
      `@keyframes twoAnimation {0% {left: ${state.warpOWidth}px;} 100% {left: -${state.textOWidth}px;}}`
    );
    computeAnimationTime();
    setTimeout(() => {
      changeAnimation();
    }, props.delay * 1000);
  });
};
// 计算 animation 滚动时长
const computeAnimationTime = () => {
  state.oneTime = state.textOWidth / props.speed;
  state.twoTime = (state.textOWidth + state.warpOWidth) / props.speed;
};
// 改变 animation 动画调用
const changeAnimation = () => {
  if (state.order === 1) {
    noticeBarTextRef.value.style.cssText = `animation: oneAnimation ${state.oneTime}s linear; opactity: 1;}`;
    state.order = 2;
  } else {
    noticeBarTextRef.value.style.cssText = `animation: twoAnimation ${state.twoTime}s linear infinite; opacity: 1;`;
  }
};
// 监听 animation 动画的结束
const listenerAnimationend = () => {
  noticeBarTextRef.value.addEventListener(
    "animationend",
    () => {
      changeAnimation();
    },
    false
  );
};
// 右侧 icon 图标点击
const onRightIconClick = () => {
  if (!props.mode) return false;
  if (props.mode === "closeable") {
    state.isMode = true;
    emit("close");
  } else if (props.mode === "link") {
    emit("link");
  }
};
// 页面加载时
onMounted(() => {
  if (props.scrollable) return false;
  initAnimation();
  listenerAnimationend();
});
</script>

<style scoped lang="scss">
.notice-bar {
  padding: 0 15px;
  width: 100%;
  border-radius: 4px;
  .notice-bar-warp {
    display: flex;
    align-items: center;
    width: 100%;
    height: inherit;
    .notice-bar-warp-text-box {
      flex: 1;
      height: inherit;
      display: flex;
      align-items: center;
      overflow: hidden;
      position: relative;
      .notice-bar-warp-text {
        white-space: nowrap;
        position: absolute;
        left: 0;
      }
      .notice-bar-warp-slot {
        width: 100%;
        white-space: nowrap;
        :deep(.el-carousel__item) {
          display: flex;
          align-items: center;
        }
      }
    }
    .notice-bar-warp-left-icon {
      width: 24px;
      font-size: inherit !important;
    }
    .notice-bar-warp-right-icon {
      width: 24px;
      text-align: right;
      font-size: inherit !important;
      &:hover {
        cursor: pointer;
      }
    }
  }
}
</style>
